// InstructionSet.h: interface for the CInstructionSet class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_INSTRUCTIONSET_H__E571CEB7_7AAF_11D2_8064_00A0C91F41A7__INCLUDED_)
#define AFX_INSTRUCTIONSET_H__E571CEB7_7AAF_11D2_8064_00A0C91F41A7__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#include "MyException.h"
#include "MyTypedef.h"
//#include "8085Object.h"
#include <afxtempl.h>

// additional information about each instruction
struct SInstructionAddInfo
{
    generic		genericType;
    specific	specificType;
    int			len;
    byte		opcode;
};

class CInstructionSet
{
public:
	void ThrowException(severity s,the_exceptions e, const CString& str);
    typedef int (CInstructionSet::*runTimeFunction)(void);
    typedef char * (CInstructionSet::*displayFunction)(word addr,char *szPrefix);   
    struct SInstruction
    {
        char *str;      // the instruction like 'nop'
        char *displayStr;  // the string to be displayed
        SInstructionAddInfo info;
        // pointer to instruction which executes it
        //runTimeFunction Execute;
        int (CInstructionSet::*Execute)(void);   
        char * (CInstructionSet::*Display)(word addr,char *szPrefix);
		// char * help_string;	// a brief help string about the instruction that can be displayed 
    };

	CInstructionSet();
    void Init();
	virtual ~CInstructionSet();

    // implementation
    int Search(char *s);
    // get the element found during the last successful search
    SInstruction & GetLastSuccessfulLookup();
    inline int GetLastSuccessfulIndex() { return m_nLastIndex; }
    inline generic GetGenericType()     { return m_SLastLookedUp->info.genericType; }
    inline specific GetSpecificType()   { return m_SLastLookedUp->info.specificType; }
    inline int GetInstructionLen()      { return m_SLastLookedUp->info.len; }
    inline int GetOpcode()              { return m_SLastLookedUp->info.opcode; }

    inline generic GetGenericType(int x)    { return m_aInstructionSet[x].info.genericType; }
    inline specific GetSpecificType(int x)  { return m_aInstructionSet[x].info.specificType; }
    inline int GetInstructionLen(int x)     { return m_aInstructionSet[x].info.len; }

    /*
	inline void Set8085Object(C8085Object *obj) { m_p8085Object = obj; }
    inline C8085Object * Get8085Object() { return m_p8085Object;}
	*/

    //Implementation
public:
	int Execute(byte opcode);
	virtual CString GetErrorPrefix();
	int Search(int x);
    //data members
protected:
    //CMap<char *,char *,SInstruction,SInstruction &> m_InstrTable;
    // table of instructions
    static SInstruction m_aInstructionSet[];
    // the result of the last successful instruction lookup
    SInstruction * m_SLastLookedUp;
    //position of last successful index
    int m_nLastIndex;
    static int m_nNumberOfInstructions;
//    C8085Object *m_p8085Object;
	static char m_szGlobalString[1024]; // global temp string 

    // implementation of the instruction set
    int VKinvalid()
    {
        ThrowException(severe,illegal_instruction,"Illegal Insruction caught at runtime");
        return 0;
    }
};

#endif // !defined(AFX_INSTRUCTIONSET_H__E571CEB7_7AAF_11D2_8064_00A0C91F41A7__INCLUDED_)
